// -----------------------------------------------
// Author:     code34 nicolas_boiteux@yahoo.fr
// Edited by:  Neumatic
// Warcontext: Main game loop
// -----------------------------------------------
if (!isServer) exitWith {};

private [
	"_count",
	"_location",
	"_marker",
	"_position",
	"_vehicle",
	"_sanity",
	"_sanity2",
	"_sanity3",
	"_numberofplayers",
	"_numberofgroup",
	"_numberofvehicle",
	"_fame",
	"_city",
	"_airmarker",
	"_marker2",
	"_positionflag",
	"_list",
	"_missionnumber",
	"_name",
	"_objective",
	"_time",
	"_buildings"
];

if (isDedicated) then {
	diag_log format ["WARCONTEXT: DEDICATED SERVER %1", wcversion];
} else {
	diag_log format ["WARCONTEXT: PC %1", wcversion];
};

_sanity = createTrigger ["EmptyDetector", wcmapcenter];
_sanity setTriggerArea [20000, 20000, 0, false];
_sanity setTriggerActivation ["EAST", "PRESENT", true];
_sanity setTriggerStatements ["this", "", ""];

_sanity2 = createTrigger ["EmptyDetector", wcmapcenter];
_sanity2 setTriggerArea [20000, 20000, 0, false];
_sanity2 setTriggerActivation ["GUER", "PRESENT", true];
_sanity2 setTriggerStatements ["this", "", ""];

_sanity3 = createTrigger ["EmptyDetector", wcmapcenter];
_sanity3 setTriggerArea [20000, 20000, 0, false];
_sanity3 setTriggerActivation ["CIV", "PRESENT", true];
_sanity3 setTriggerStatements ["this", "", ""];

while {(wclevel < wclevelmax) and (wcteamscore < wcscorelimitmax)} do {
	// Compute missions list
	wcgarbage = [] spawn WC_fnc_createlistofmissions;

	wccurrentmission = nil;
	wcmissionsuccess = false;
	wcnumberofkilledofmissionW = 0;
	wcnumberofkilledofmissionE = 0;
	wcnumberofkilledofmissionC = 0;
	wcnumberofkilledofmissionV = 0;
	wcteambonus = 0;

	_count = 60;
	while {isNil "wccurrentmission"} do {
		_count = _count + 1;
		if (_count > 60) then {
			wcchoosemission = true;
			["wcchoosemission", "client"] call WC_fnc_publicvariable;
			["wclistofmissions", "client"] call WC_fnc_publicvariable;
			if !(isDedicated) then {
				if (wcchoosemission) then {
					wcmessageW = [localize "STR_WC_MESSAGEMISSIONCOMMANDEMENT", localize "STR_WC_MENUCHOOSEMISSION"];
					//if !(isDedicated) then {wcgarbage = wcmessageW spawn EXT_fnc_infotext};
					["wcmessageW", "client"] call WC_fnc_publicvariable;
					if (isNil "wcchoosemissionmenu") then {
						wcchoosemissionmenu = player addAction ["<t color='#dddd00'>" + localize "STR_WC_MENUCHOOSEMISSION" + "</t>", "warcontext\dialogs\WC_fnc_createmenuchoosemission.sqf", [], 6, false];
					};
				} else {
					player removeAction wcchoosemissionmenu;
					wcchoosemissionmenu = nil;
				};
			};
			_count = 0;
		};
		sleep 1;
	};

	// Reset missions list
	wclistofmissions = [];

	// Turn off player menu
	wcchoosemission = false;
	["wcchoosemission", "client"] call WC_fnc_publicvariable;
	
	// Retrieve mission informations
	_missionnumber   = wccurrentmission select 0;
	_name            = wccurrentmission select 1;
	_objective       = wccurrentmission select 2;
	_city            = wccurrentmission select 3;
	_numberofgroup   = wccurrentmission select 4;
	_numberofvehicle = wccurrentmission select 5;
	_position        = wccurrentmission select 6;
	_time            = wccurrentmission select 7;

	_location = createLocation ["Strategic", _position, 50, 50];
	wcmissionlocations = wcmissionlocations + [_location];
	wcmissiondone = wcmissiondone + [_missionnumber];

	if ((_time select 3) < (date select 3)) then {wcday = wcday + 1; wcfame = (wcfame - 0.15)};
	if ((_time select 3) == (date select 3)) then {if ((_time select 4) < (date select 4)) then {wcday = wcday + 1; wcfame = (wcfame - 0.15)};};

	// Delete zones for next mission near this zone
	wclastmissionposition = _position;
	wcmissionposition = _position;

	//A3 TODO: Remove this?
	// Check if we are in town or not
	_buildings = nearestObjects [position _location, ["House"] , wcdistance];
	if (count _buildings < wcminimunbuildings) then {
		wcgarbage = [_location, wcvillagehouses] call WC_fnc_computeavillage;
		wcgarbage = [_location] spawn WC_fnc_popcivilian;
	};

	if (wcskiptime > 0) then {
		wcdate = _time;
		if (isDedicated) then {
			setDate wcdate;
		};
		["wcdate", "client"] call WC_fnc_publicvariable;
		["wcday", "client"] call WC_fnc_publicvariable;
	};

	diag_log format ["WARCONTEXT: COMPUTING LOCATION %1", text _location];

	// Send mission text to player
	if (isNil text _location) then {
		_city = nearestLocation [position _location, "NameCity"];
		wcmessageW = [format ["Mission %1", wcmissioncount], format [localize "STR_WC_MESSAGENEAR", text _city], localize "STR_WC_MESSAGETAKISTANLOCALISED"];
	} else {
		wcmessageW = [format ["Mission %1", wcmissioncount], format [localize "STR_WC_MESSAGEGOTO", text _location], localize "STR_WC_MESSAGETAKISTANLOCALISED"];
	};
	["wcmessageW","client"] call WC_fnc_publicvariable;

	_marker = ["rescuezone", wcdistance, _position, "ColorRed", "ELLIPSE", "FDIAGONAL", "", 0, "", false] call WC_fnc_createmarker;

	if (wcairopposingforce > 0) then {
		_airmarker = ["airzone", 2000, _position, "ColorGreen", "ELLIPSE", "FDIAGONAL", "", 0, "", false] call WC_fnc_createmarkerlocal;
	};

	if (wcwithmarkerongoal > 0) then {
		_marker2 = ["operationtext", 0.5, _position, "ColorRed", "ICON", "FDIAGONAL", "flag", 0, (localize (format ["STR_WCSHORT_MISSION%1", _missionnumber])), false] call WC_fnc_createmarker;
	};

	wcselectedzone = _position;
	["wcselectedzone", "client"] call WC_fnc_publicvariable;

	// Build bombing mortar
	if ((random 1 < wcmortarprobability) and (_numberofvehicle > 0) and (_numberofgroup > 0)) then {
		wcgarbage = [_marker] spawn WC_fnc_mortar;
	};

	// Create anti air
	if (wcwithantiairsite > 0) then {
		for "_x" from 0 to ceil(random (wcaalevel - 1)) do {
			wcgarbage = [] spawn WC_fnc_antiair;
			sleep 0.05;
		};
	};

	// Create enemies on target
	for "_x" from 1 to _numberofgroup do {
		wcgarbage = [_marker, wcfactions call BIS_fnc_selectRandom, false] spawn WC_fnc_creategroup;
		sleep 2;
	};

	// Create enemies vehicles on target
	for "_x" from 1 to _numberofvehicle do {
		wcgarbage = [_marker, (wcvehicleslistE call BIS_fnc_selectRandom), true] spawn WC_fnc_creategroup;
		sleep 2;
	};

	// Create x convoy on map
	for "_x" from 1 to wcconvoylevel do {
		wcgarbage = [wcvehicleslistE, wcconvoyvehicles, (round (random 3))] spawn WC_fnc_createconvoy;
		sleep 2;
	};

	// Create side mission
	wcgarbage = [_missionnumber, _name] spawn WC_fnc_createsidemission;

	// Create enemies on other zone near side mission
	wcgarbage = [_location] spawn WC_fnc_ambiantlife;

	// Create reinforcment groups
	if (wcreinforcmentlevel > 0) then { 
		wcgarbage = [_location, _marker] spawn WC_fnc_support;
	};

	// Create enemies base around
	if (wcwithcomposition == 1) then {
		wcgarbage = [_location] spawn WC_fnc_createcomposition;
	};

	// Create static weapons in building
	if (wcwithstaticweapons == 1) then {
		wcgarbage = [_position] spawn WC_fnc_createstatic;
	};

	// Create mhq near mission zone
	if (wcwithmhq == 1) then {
		wcgarbage = [_position] spawn WC_fnc_createmhq;
	};

	// Create logics
	{
		if (wcwithcivilcar > 0) then {
			wcgarbage = [position _x] spawn WC_fnc_createcivilcar;
		};
		if (wcwithied > 0) then {
			if ((random 1 > 0.9) and ((position _x) distance (getMarkerPos "respawn_west") > 1000)) then {
				wcgarbage = [position _x] spawn WC_fnc_createiedintown;
			};
		};
		if (wcwithminefield > 0) then {
			if ((random 1 > 0.9) and ((position _x) distance (getMarkerPos "respawn_west") > 1000)) then {
				wcgarbage = [position _x] spawn WC_fnc_createminefield;
			};
		};
		sleep 1;
	} foreach wctownlocations;

	// Wait until the end of Mission - use while instead of waitUntil - performance leak
	while {!wcmissionsuccess} do {sleep 1};
	wcmissionsuccess = false;

	// Increase objective cursor
	wcobjectiveindex = wcobjectiveindex + 1;

	"operationtext" setMarkerText "Mission is finished. Leave the zone";

	//A3 TODO: setVehicleInit
	if (wcwithteleportflagatend == 1) then {
		_positionflag = (position _location) findEmptyPosition [10, 300];
		if (_positionflag select 0 == 0) then {
			diag_log "WARCONTEXT: NO FOUND EMPTY POSITION FOR TELEPORT FLAG";
		};
		wcflag = "FlagCarrierUSA_EP1" createVehicle _positionflag;
		wcflag setVehicleInit "this allowDammage false; wcrtb = this addAction ['<t color=''#dddd00''>Teleport to base</t>', 'warcontext\actions\WC_fnc_doreturntobase.sqf', [], -1, false];";
		processInitCommands;
		_marker = [format ['teleportflag%1',wcteleportindex], 0.5, _position, "ColorGreen", "ICON", "FDIAGONAL", "City", 0, "", false] call WC_fnc_createmarker;
		wcteleportindex = wcteleportindex + 1;
	};

	_numberofplayers = 100;
	_count = 0;
	while {_numberofplayers >= (ceil((playersNumber west) * wcleaversatendofmission))} do {
		_list = [];
		{	
			if (isPlayer _x) then {
				if (_x distance (position _location) < wcleaveareasizeatendofmission) then {
					_list = _list + [_x];
				};
			};
		} foreach allUnits;

		_numberofplayers = count _list;
		sleep 10;

		if (_numberofplayers >= (ceil((playersNumber west) * wcleaversatendofmission))) then { 
			_count = _count + 1;
			if (_count > 10) then {
				_count = 0;
				wcmessageW = [format [localize "STR_WC_MESSAGEMISSIONCOMMANDEMENT", wclevel], localize "STR_WC_MESSAGELEAVEZONE"];
				["wcmessageW", "client"] call WC_fnc_publicvariable;
			};
		};
	};

	// The mission is finished - All players are out of zone

	wcradio removeAllEventHandlers "HandleDamage";
	wcheavyfactory removeAllEventHandlers "HandleDamage";
	wcbarrack removeAllEventHandlers "HandleDamage";

	//sleep 30;

	wcheavyfactory setDamage 1;
	wcbarrack setDamage 1;
	wcradio setDamage 1;
	deleteVehicle wcradio;
	deleteVehicle wcgenerator;

	deleteMarker "rescuezone";
	deleteMarker "operationtext";
	deleteMarker "sidezone";
	deleteMarker "bombzone";
	deleteMarker "iedzone";
	deleteMarker "radiotower";
	deleteMarker "generator";
	deleteMarkerLocal "airzone";

	wcmessageW = [format [localize "STR_WC_MESSAGEMISSIONFINISHED", wcmissioncount], localize "STR_WC_MESSAGNEXTSTEP"];
	["wcmessageW", "client"] call WC_fnc_publicvariable;

	sleep 0.5;

	// Print stats before saniting map
	wcmessageW = ["Casualty", format ["%1 East soldiers killed", wcnumberofkilledofmissionE]];
	["wcmessageW", "client"] call WC_fnc_publicvariable;

	sleep 0.5;

	wcmessageW = ["Casualty", format ["%1 West soldiers killed", wcnumberofkilledofmissionW]];
	["wcmessageW", "client"] call WC_fnc_publicvariable;

	sleep 0.5;

	wcmessageW = ["Casualty", format ["%1 Civils killed", wcnumberofkilledofmissionC]];
	["wcmessageW", "client"] call WC_fnc_publicvariable;

	sleep 0.5;

	wcmessageW = ["Casualty", format ["%1 Vehicles destroyed", wcnumberofkilledofmissionV]];
	["wcmessageW", "client"] call WC_fnc_publicvariable;

	sleep 0.5;

	if (ceil (wcfame * 100) > 75) then {
		_fame = "Very Good";
	} else {
		if (ceil (wcfame * 100) > 50) then {
			_fame = "Good";
		} else {
			if (ceil (wcfame * 100) > 25) then {
				_fame = "Bad";
			} else {
				_fame = "Ugly";
			};
		};
	};
	wcmessageW = ["Military intervention", format ["%1 fame", _fame]];
	["wcmessageW", "client"] call WC_fnc_publicvariable;

	sleep 0.5;

	// If arcade == 1
	if (wckindofgame == 1) then {
		wcteamplayscoretoadd = ceil((wcnumberofkilledofmissionE - wcnumberofkilledofmissionW + wclevel + wcteambonus + (wcnumberofkilledofmissionV * 3)) / (playersNumber west));
	} else {
		wcteamplayscoretoadd = ceil((wcnumberofkilledofmissionE - wcnumberofkilledofmissionW - wcnumberofkilledofmissionC + wclevel + wcteambonus + (wcnumberofkilledofmissionV * 3)) / (playersNumber west));
	};

	if (wcteamplayscoretoadd < 0) then {wcteamplayscoretoadd = 0};

	// Send points to share
	if (wcleveltoadd > 0) then {
		if (wckindofgame == 1) then {
			wcteamscore = wcteamscore + 5;
		} else {
			wcteamscore = wcteamscore + 3;
		};
		["wcteamplayscoretoadd", "client"] call WC_fnc_publicvariable;
	};

	// Sanitizing map
	diag_log "WARCONTEXT: MISSION FINISHED - SANITIZING MAP";

	{
		_vehicle = _x;
		if (count (crew _vehicle) == 0) then {
			_vehicle setDamage 1;
			deleteVehicle _vehicle;
		};
		sleep 0.1;
	} foreach wcvehicles;

	_list = list _sanity;
	sleep 2;
	{
		if !(isPlayer _x) then {
			if (format ["%1", _x getVariable "wcprotected"] == "<null>") then {
				_x removeAllEventHandlers "Killed";
				_x setDamage 1;
				deleteVehicle _x;
				sleep 0.05;
			};
		};
		sleep 0.05;
	} foreach _list;

	_list = list _sanity2;
	sleep 2;
	{
		if !(isPlayer _x) then {
			if (_x isKindOf "Man") then {
				if (format ["%1", _x getVariable "wcprotected"] == "<null>") then {
					_x removeAllEventHandlers "Killed";
					_x setDamage 1;
					deleteVehicle _x;
					sleep 0.05;
				};
			};
		};
		sleep 0.05;
	} foreach _list;

	_list = list _sanity3;
	sleep 2;
	{
		if !(isPlayer _x) then {
			if (_x isKindOf "Man") then {
				if (format ["%1", _x getVariable "wcprotected"] == "<null>") then {
					_x removeAllEventHandlers "Killed";
					_x setDamage 1;
					deleteVehicle _x;
					sleep 0.05;
				};
			};
		};
		sleep 0.05;
	} foreach _list;

	{
		if ((west countSide (crew _x)) == 0) then {
			if (format ["%1", _x getVariable "wcprotected"] == "<null>") then {
				_x removeAllEventHandlers "Killed";
				_x setDamage 1;
				deleteVehicle _x;
			};
		};
		sleep 0.05;
	} foreach wcblinde;

	{
		if ((west countSide (crew _x)) == 0) then {
			if (format ["%1", _x getVariable "wcprotected"] == "<null>") then {
				_x removeAllEventHandlers "Killed";
				_x setDamage 1;
				deleteVehicle _x;
			};
		};
		sleep 0.05;
	} foreach wcunits;

	for "_x" from 1 to wcambiantindex do {
		call compile format ["deleteMarkerLocal ambiant%1;", _x];
		sleep 0.05;
	};

	{
		deleteMarkerLocal _x;
		sleep 0.05;
	} foreach wcambiantmarker;

	{
		deleteVehicle _x;
		sleep 0.05;
	} foreach wcammobox;

	{
		if ((west countSide (crew _x)) == 0) then {
			if (format ["%1", _x getVariable "wcprotected"] == "<null>") then {
				_x removeAllEventHandlers "Killed";
				_x setDamage 1;
				deleteVehicle _x;
			};
		};
		sleep 0.05;
	} foreach wcobjecttodelete;

	{
		if (count (units _x) == 0) then {
			deleteGroup _x;
		};
		sleep 0.05;
	} foreach allGroups;

	wcambiantindex = 0;

	wclevel = wclevel + wcleveltoadd;
	wcmissioncount = wcmissioncount + 1;
	wcleveltoadd = 0;
	wcskill = wcskill + 0.02;
	["wcskill", "client"] call WC_fnc_publicvariable;
	["wclevel", "client"] call WC_fnc_publicvariable;
	["wcmissioncount", "client"] call WC_fnc_publicvariable;
	["wcenemykilled", "client"] call WC_fnc_publicvariable;
	wcdistance = wcdistance + wcdistancegrowth;

	wcblinde = [];
	wcunits = [];
	wcvehicles = [];
	wcobjecttodelete = [];
	wcallaaposition = [];

	wcalert = 0;
	["wcalert", "client"] call WC_fnc_publicvariable;
	diag_log "WARCONTEXT: SANITIZING: MISSION IS FINISHED";
	sleep (60 + random 120);
};